package com.gree.flowable.app.services.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gree.flowable.app.mapper.*;
import com.gree.flowable.app.mapper.plus.FormBusinessInfoService;
import com.gree.flowable.app.mapper.plus.FormModelService;
import com.gree.flowable.app.pojo.form.*;
import com.gree.flowable.app.pojo.vo.ReturnVO;
import com.gree.flowable.app.services.IFlowableBpmnModelService;
import com.gree.flowable.app.services.IFlowableFormDetailService;
import com.gree.flowable.app.services.IFormInfoService;
import com.gree.flowable.app.tools.constants.ReturnCode;
import org.flowable.bpmn.model.FlowNode;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author ：180849
 * @date ：Created in 2021/5/6 10:06
 * @description：获取审批表单的详细信息
 * @modified By：
 * @version: 1.0
 */
@Service
public class IFlowableFormDetailServiceImpl implements IFlowableFormDetailService {

    @Autowired
    private IFlowableBpmnModelService iFlowableBpmnModelService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private IFormInfoService formInfoService;

    @Autowired
    private FormModelService formModelService;

    @Autowired
    private FormModelMapper formModelMapper;

    @Autowired
    private HistoryService historyService;

    @Autowired
    private FormDataMapper formDataMapper;

    @Autowired
    private FlwFormNodesetMapper flwFormNodesetMapper;

    @Autowired
    private FormBusinessMapper formBusinessMapper;

    @Autowired
    private FormBusinessInfoMapper formBusinessInfoMapper;

    @Autowired
    private FormBusinessInfoService formBusinessInfoService;


    @Autowired
    private FlwFormNodesetBusinessMapper flwFormNodesetBusinessMapper;

    @Override
    public ReturnVO getProcessDetail(String taskId) {
        ReturnVO result = null;
        Map<String, Object> resultMap = new HashMap<>();
        //根据taskId获取当前节点
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        FlowNode activityNode = iFlowableBpmnModelService.findFlowNodeByActivityId(task.getProcessDefinitionId(), task.getTaskDefinitionKey());
        String elementId = activityNode.getId();
        String processDefinitionId = task.getProcessDefinitionId();

        //根据taskID获取模型id
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult();
        String processKey = processDefinition.getKey();

        //根据taskID获取单号
        String processInstanceId = task.getProcessInstanceId();
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        String businessKey = processInstance.getBusinessKey();

        //获取在各个节点不同组件的状态，0为disable，1为readOnly
        //进行改造，发起后从进程中查询
        QueryWrapper<FlwFormNodesetBusiness> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(FlwFormNodesetBusiness::getProcessKey, processKey).eq(FlwFormNodesetBusiness::getElementId, elementId).eq(FlwFormNodesetBusiness::getBusinessKey,businessKey);
        FlwFormNodesetBusiness flwFormNodesetBusiness = flwFormNodesetBusinessMapper.selectOne(queryWrapper);
        List<String> disableArray = new LinkedList<>();
        List<String> readOnlyArray = new LinkedList<>();
        List<String> editArray = new LinkedList<>();
//        if (flwFormNodeset == null){
//            QueryWrapper<FormBusinessInfo> fbiwq = new QueryWrapper<>();
//            fbiwq.lambda().eq(FormBusinessInfo::getBusinessKey,businessKey);
//            List<FormBusinessInfo> formBusinessInfoList = formBusinessInfoMapper.selectList(fbiwq);
//            for (FormBusinessInfo formBusinessInfo : formBusinessInfoList) {
//                String fields = formBusinessInfo.getFields();
//                readOnlyArray.add(fields);
//            }
//
//        } else {
            String formDesc = flwFormNodesetBusiness.getFormDesc();
            JSONObject formDescJson = JSONObject.parseObject(formDesc);

            for (Map.Entry<String, Object> map: formDescJson.entrySet()){
                String key = map.getKey();
                String value = map.getValue().toString();
                if ("0".equals(value)){
                    disableArray.add(key);
                }
                if ("1".equals(value)){
                    readOnlyArray.add(key);
                }
                if("2".equals(value)){
                    editArray.add(key);
                }
            }
//        }

        /*Map<String, Object> flwNodesetMap = new HashMap<>();
        flwNodesetMap.put("processKey",flwFormNodeset.getProcessKey());
        flwNodesetMap.put("elementId",flwFormNodeset.getElementId());
        flwNodesetMap.put("formId",flwFormNodeset.getFormId());
        flwNodesetMap.put("disableArray",disableArray);
        flwNodesetMap.put("readOnlyArray",readOnlyArray);*/

        //获取formId
//        String formId = flwFormNodesetMapper.getFormId(processKey);
        String formId = formBusinessMapper.getFormId(businessKey);

        //获取表单信息
        FormInfo formInfo = formInfoService.queryFormById(formId);
        //获取表单组件
//        QueryWrapper<FormModel> formModelQW = new QueryWrapper<>();
//        formModelQW.lambda().eq(FormModel::getFormId, formId);
//        List<FormModel> formModelList = formModelService.list(formModelQW);
        //获取表单数据
        QueryWrapper<FormBusinessInfo> fbiqw = new QueryWrapper<>();
        fbiqw.lambda().eq(FormBusinessInfo::getBusinessKey,businessKey);
        List<FormBusinessInfo> formBusinessInfoList = formBusinessInfoService.list(fbiqw);
//        Map<String, Object> formDataMap = formDataMapper.quryData(businessKey, formId);
        Map<String, Object> formData = new HashMap<>();
        /*for (String key : formDataMap.keySet()) {
            String newKey = key.toLowerCase();
            //判断是否为上传文件的组件
            QueryWrapper<FormModel> formModelQW = new QueryWrapper<>();
            formModelQW.lambda().eq(FormModel::getFormId,formId).eq(FormModel::getFields,newKey);
            FormModel formModel = formModelMapper.selectOne(formModelQW);
            //如果为上传文件的组件，将String转为List
            if (!"BUSINESS_KEY".equals(key) &&"upload-file".equals(formModel.getShape())){
                List<Object> uploadInfo = (List<Object>) JSON.parse(formDataMap.get(key).toString());
                formData.put(newKey,uploadInfo);
                continue;
            }
            //如果组件为checkbox多选框，将String转为List传给前台
            if (!"BUSINESS_KEY".equals(key) &&"checkbox".equals(formModel.getShape())){
                List<Object> list = JSON.parseArray(formDataMap.get(key).toString());
                formData.put(newKey,list);
                continue;
            }

            formData.put(newKey,formDataMap.get(key));
        }*/
        for (FormBusinessInfo formBusinessInfo : formBusinessInfoList) {
            String fields = formBusinessInfo.getFields();
            String fieldType = formBusinessInfo.getFieldType();
            QueryWrapper<FormModel> formModelQW = new QueryWrapper<>();
            formModelQW.lambda().eq(FormModel::getFormId,formId).eq(FormModel::getFields,fields);
            FormModel formModel = formModelMapper.selectOne(formModelQW);

            switch (fieldType){
                case "Date":
                case "Time":
                    formData.put(fields,formBusinessInfo.getLvaldate());
                    break;
                case "Integer":
                case "Double":
                    formData.put(fields,formBusinessInfo.getValnum());
                    break;
                case "String":
                default:
                    formData.put(fields,formBusinessInfo.getValstr());
                    if ("checkbox".equals(formModel.getShape())) {
                        List<Object> list = JSON.parseArray(formBusinessInfo.getValstr());
                        formData.put(fields,list);
                    }
            }
        }
        Map<String, Integer> nextNodesMap = iFlowableBpmnModelService.findNextNodesByTask(task);

        resultMap.put("disableArray",disableArray);
        resultMap.put("readOnlyArray",readOnlyArray);
        resultMap.put("editArray",editArray);
        resultMap.put("formInfo", formInfo);
        resultMap.put("formDataMap", formData);
        resultMap.put("nextNodesMap", nextNodesMap);
        resultMap.put("formName", processInstance.getName());
        resultMap.put("businessKey", businessKey);
        result = new ReturnVO(ReturnCode.SUCCESS, "查询成功", resultMap);
        return result;
    }

    @Override
    public ReturnVO getProcessDetail(String businessKey, String nodeKey) {
        ReturnVO result = null;
        Map<String, Object> resultMap = new HashMap<>();

        HistoricProcessInstance instance = historyService.createHistoricProcessInstanceQuery().processInstanceBusinessKey(businessKey).singleResult();

        String processKey = instance.getProcessDefinitionKey();

        QueryWrapper<FlwFormNodesetBusiness> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(FlwFormNodesetBusiness::getProcessKey, processKey).eq(FlwFormNodesetBusiness::getElementId, nodeKey).eq(FlwFormNodesetBusiness::getBusinessKey,businessKey);
        FlwFormNodesetBusiness flwFormNodesetBusiness = flwFormNodesetBusinessMapper.selectOne(queryWrapper);
        List<String> disableArray = new LinkedList<>();
        List<String> readOnlyArray = new LinkedList<>();
        List<String> editArray = new LinkedList<>();
        String formDesc = flwFormNodesetBusiness.getFormDesc();
        JSONObject formDescJson = JSONObject.parseObject(formDesc);

        for (Map.Entry<String, Object> map: formDescJson.entrySet()){
            String key = map.getKey();
            String value = map.getValue().toString();
            if ("0".equals(value)){
                disableArray.add(key);
            }
            if ("1".equals(value)){
                readOnlyArray.add(key);
            }
            if("2".equals(value)){
                readOnlyArray.add(key);
//                editArray.add(key);
            }
        }

        String formId = formBusinessMapper.getFormId(businessKey);
        FormInfo formInfo = formInfoService.queryFormById(formId);

        QueryWrapper<FormBusinessInfo> fbiqw = new QueryWrapper<>();
        fbiqw.lambda().eq(FormBusinessInfo::getBusinessKey,businessKey);
        List<FormBusinessInfo> formBusinessInfoList = formBusinessInfoService.list(fbiqw);

        Map<String, Object> formData = new HashMap<>();

        for (FormBusinessInfo formBusinessInfo : formBusinessInfoList) {
            String fields = formBusinessInfo.getFields();
            String fieldType = formBusinessInfo.getFieldType();
            QueryWrapper<FormModel> formModelQW = new QueryWrapper<>();
            formModelQW.lambda().eq(FormModel::getFormId,formId).eq(FormModel::getFields,fields);
            FormModel formModel = formModelMapper.selectOne(formModelQW);

            switch (fieldType){
                case "Date":
                case "Time":
                    formData.put(fields,formBusinessInfo.getLvaldate());
                    break;
                case "Integer":
                case "Double":
                    formData.put(fields,formBusinessInfo.getValnum());
                    break;
                case "String":
                default:
                    formData.put(fields,formBusinessInfo.getValstr());
                    if ("checkbox".equals(formModel.getShape())) {
                        List<Object> list = JSON.parseArray(formBusinessInfo.getValstr());
                        formData.put(fields,list);
                    }
            }
        }

        resultMap.put("disableArray",disableArray);
        resultMap.put("readOnlyArray",readOnlyArray);
        resultMap.put("editArray",editArray);
        resultMap.put("formInfo", formInfo);
        resultMap.put("formDataMap", formData);
        resultMap.put("formName", instance.getName());
        resultMap.put("businessKey", businessKey);
        result = new ReturnVO(ReturnCode.SUCCESS, "查询成功", resultMap);
        return result;
    }
}
